package system.service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import net.apexcns.core.util.LogUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import system.common.Arguments;
import system.common.Constants;
import system.model.DB10_iDeskDto;
import system.model.DB1_WebkeeperDto;
import system.model.DB2_MsgIDto;
import system.model.DB3_DbIDto;
import system.model.DB4_PrivacyIDto;
import system.model.DB5_NetKeyDto;
import system.model.DB6_RedcastleDto;
import system.model.DB7_PowerBrokerDto;
import system.model.DB8_TxLoggingDto;
import system.model.DB9_PortalLoginDto;
import collector.core.CollectConstants;
import collector.core.TaskConstVO;
import collector.core.config.ConfigModule;
import collector.core.util.DateUtil;
import collector.core.util.FileUtil;
import collector.task.JobStateVO;

/**
 * <pre>
 * Class : system.ExportService / ExportService.java
 * 	Define Class Object : 
 * <br>
 * </pre>
 * @author ytjeong / apexcns,Inc.
 * @author hwanLee / apexcns,Inc.
 * @version 1.0
 * @see javadoc
 * @since 2012. 9. 20.
 */
public class ExportService {
	private static Logger _log = LoggerFactory.getLogger(ExportService.class);
	private static final String _LogPrefixStr = CollectConstants.LOGGER_MODULE_NAME_SMC + CollectConstants.LOGGER_MODULE_NAME_AFTFIX;//"test Log> ";

	@SuppressWarnings({ "unchecked" })
	public static int OutputList(List<?> dtoRec, Writer writer, String historyFileName, String stepNumber, int fileCount, String cmd) throws IOException {
	    // 코드 수정 retOutFileCount [By Jeong 2012.09.18]
		int retOutFileCount = 1;
		long currentFileSize = 0;
		File file = null;
		String fileNumber = FileUtil.genFileNumber(fileCount);
		
		if (dtoRec.size() > 0) {
			Object o = dtoRec.get(0);
			if (o instanceof DB1_WebkeeperDto) {
				for (DB1_WebkeeperDto record : (List<DB1_WebkeeperDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					if (cmd.equals("WEBKEEPER_01")) {
						writer.write(record.toString());	
					} else if (cmd.equals("WEBKEEPER_02")) {
						writer.write(record.toString());
					} else if (cmd.equals("WEBKEEPER_MIGRATE_01")) {
						writer.write(record.toString());
					} else if (cmd.equals("WEBKEEPER_MIGRATE_02")) {
						writer.write(record.toString());
					}
				}
			} else if (o instanceof DB2_MsgIDto) {
				for (DB2_MsgIDto record : (List<DB2_MsgIDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					if (cmd.equals("MSG_I_01")) {
						writer.write(record.toStringMail());	
					} else if (cmd.equals("MSG_I_02")) {
						writer.write(record.toStringFile());
					} else if (cmd.equals("MSG_I_03")) {
						writer.write(record.toStringBlock());
					}
				}
			} else if (o instanceof DB3_DbIDto) {
				for (DB3_DbIDto record : (List<DB3_DbIDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					writer.write(record.toString());
				}
			} else if (o instanceof DB4_PrivacyIDto) {
				for (DB4_PrivacyIDto record : (List<DB4_PrivacyIDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					writer.write(record.toString());
				}
			} else if (o instanceof DB5_NetKeyDto) {
				for (DB5_NetKeyDto record : (List<DB5_NetKeyDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					writer.write(record.toString());
				}
			} else if (o instanceof DB6_RedcastleDto) {
				for (DB6_RedcastleDto record : (List<DB6_RedcastleDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					if (cmd.equals("REDCASTLE_01")) {
						writer.write(record.toStringLoginlog());
					} else if (cmd.equals("REDCASTLE_03")) {
						writer.write(record.toStringFtplog());
					} else if (cmd.equals("REDCASTLE_03")) {
						writer.write(record.toStringSessionlog());
					}
				}
			} else if (o instanceof DB7_PowerBrokerDto) {
				for (DB7_PowerBrokerDto record : (List<DB7_PowerBrokerDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					if (cmd.equals("POWERBROKER_01")) {
						writer.write(record.toStringInput());
					} else if (cmd.equals("POWERBROKER_02")) {
						writer.write(record.toStringOutput());
					}
				}
			} else if (o instanceof DB8_TxLoggingDto) {
				for (DB8_TxLoggingDto record : (List<DB8_TxLoggingDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					writer.write(record.toString());
				}
			} else if (o instanceof DB9_PortalLoginDto) {
				for (DB9_PortalLoginDto record : (List<DB9_PortalLoginDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					writer.write(record.toString());
				}
			} else if (o instanceof DB10_iDeskDto) {
				for (DB10_iDeskDto record : (List<DB10_iDeskDto>) dtoRec) {
					currentFileSize = currentFileSize + record.toString().getBytes().length;
					if (currentFileSize >= Constants.maxFileSize) {
						writer.flush();
						writer.close();

						currentFileSize = 0;
						fileCount++;
						fileNumber = FileUtil.genFileNumber(fileCount);
						file = new File(historyFileName + stepNumber + fileNumber + Constants.fileNameExtension);
						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
					}
					writer.write(record.toString());
				}
			}
		}
		writer.flush();
		writer.close();
		
		// 코드 수정 retOutFileCount [By Jeong 2012.09.18]
		retOutFileCount = retOutFileCount + fileCount;
		return retOutFileCount;
	}
	
	/**
	 * <pre>
	 * Method : ExportService.OutputStateLog()
	 * 	Task Job 관련 VO 객체를 이용한 Job State를 생성한다.
	 * <br>
	 * @param jsVo
	 * @return 
	 * type of void
	 * </pre>
	 */	
	public static void OutputStateLog(JobStateVO jsVo) throws IOException {
		if (jsVo.isJobAuto() == true) {
			TaskConstVO tcVo = ConfigModule.newInstance().getModuleTask(jsVo.getJobIDs());
			
			String logFileName = null;
			
			if (jsVo.getJobState().equals(CollectConstants.CODE_JOB_STATE_DOING)) {
				logFileName = tcVo.getTaskName() + "_" + CollectConstants.STATE_CURRENT;

				// check for directory
				FileUtil.directoryCheck(tcVo.getTaskPathState());
				
				LogUtil.logDisp(_log, _LogPrefixStr, "State Monitor - Current (Doing)", " " + jsVo.getJobIDs() + " :: " + jsVo.toStringCurrent(), CollectConstants.LOG_INFO );
				LogUtil.logDisp(_log, _LogPrefixStr, "State Monitor - Past", " " + jsVo.getJobIDs() + " :: " + jsVo.toStringPast(), CollectConstants.LOG_INFO );
			} else if (jsVo.getJobState().equals(CollectConstants.CODE_JOB_STATE_DONE)) {
				logFileName = tcVo.getTaskName() + "_" + CollectConstants.STATE_PAST;
				
				LogUtil.logDisp(_log, _LogPrefixStr, "State Monitor - Current (Done)", " " + jsVo.getJobIDs() + " :: " + jsVo.toStringPast(), CollectConstants.LOG_INFO );
			}  else if (jsVo.getJobState().equals(CollectConstants.CODE_JOB_STATE_WILL_DO)) {
				logFileName = tcVo.getTaskName() + "_" + CollectConstants.STATE_NEXT;
				
				LogUtil.logDisp(_log, _LogPrefixStr, "State Monitor - Next", " " + jsVo.getJobIDs() + " :: " + jsVo.toStringNext(), CollectConstants.LOG_INFO );
			}
			File file = new File(tcVo.getTaskPathState() + logFileName);
			//FIXME:: Write XML
			net.apexcns.core.util.XmlBindUtil.toXmlWithNd(JobStateVO.class, jsVo, file);
		}
	}

	public static void getNextSchedule(JobStateVO jsVo, TaskConstVO tcVo, Arguments arguments) throws IOException {
		Date nextDate = null;
		Date currentDate = jsVo.getScheduleTime();
		String condStartTime = null;
		String condEndTime = null;
		if (tcVo.getDurationType().equals("DAY")) {
			nextDate = DateUtil.dateAdd(Calendar.DATE, tcVo.getDurationValue(), currentDate);
			condStartTime = DateUtil.dateAddFormat(Calendar.DATE, -(tcVo.getDurationValue() - 1), nextDate);
			condEndTime = DateUtil.dateAddFormat(Calendar.DATE, 0, nextDate);
		} else if (tcVo.getDurationType().equals("HOUR")) {
			nextDate = DateUtil.dateAdd(Calendar.HOUR, tcVo.getDurationValue(), currentDate);
			condStartTime = DateUtil.dateAddFormat(Calendar.HOUR, -(tcVo.getDurationValue() - 1), nextDate);
			condEndTime = DateUtil.dateAddFormat(Calendar.HOUR, 0, nextDate);
		} else if (tcVo.getDurationType().equals("MIN")) {
			nextDate = DateUtil.dateAdd(Calendar.MINUTE, tcVo.getDurationValue(), currentDate);
			condStartTime = DateUtil.dateAddFormat(Calendar.MINUTE, -(tcVo.getDurationValue() - 1), nextDate);
			condEndTime = DateUtil.dateAddFormat(Calendar.MINUTE, 0, nextDate);
		} else if (tcVo.getDurationType().equals("SEC")) {
			nextDate = DateUtil.dateAdd(Calendar.SECOND, tcVo.getDurationValue(), currentDate);
			condStartTime = DateUtil.dateAddFormat(Calendar.SECOND, -(tcVo.getDurationValue() - 1), nextDate);
			condEndTime = DateUtil.dateAddFormat(Calendar.SECOND, 0, nextDate);
		}
		JobStateVO pjsVo = new JobStateVO();
		pjsVo.setJobIDs(jsVo.getJobIDs());
		pjsVo.setJobDurationValue(jsVo.getJobDurationValue());
		pjsVo.setScheduleTime(nextDate);
		pjsVo.setJobCondStartTime(DateUtil.trim(condStartTime));
		pjsVo.setJobCondEndTime(DateUtil.trim(condEndTime));
		pjsVo.setJobState(CollectConstants.CODE_JOB_STATE_WILL_DO);
		ExportService.OutputStateLog(pjsVo);
	}
}